package controler.tools;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import model.data.DataSet;
import model.data.Measurement;

public class DataAnalysis {
	private WritableWorkbook workbook;
	private WritableSheet sheet;
	private int index;
	private DataSet dataSet;
	
	public DataAnalysis(DataSet dataSet) {
		this.dataSet = dataSet;
	}
	
	public void process()
	{
		LinkedList<double []> dataSet = toListOfArrays(this.dataSet.getList());
		try {
		for(int i=1; i<dataSet.getFirst().length; i++)
		{
			if(i == 5);
			else
			{				
					workbook = Workbook.createWorkbook(new File("z"+i+".xls"));
					sheet = workbook.createSheet("First Sheet", 0);
					
					int j = 0;
					double avg = 0;
					double k = -1;
					boolean flag = false;
					for (double [] values : dataSet)
					{
						double value = values[i];
						double intensity = values[5];
						
						avg += value / (double)dataSet.size();
						if(Math.random() > 0.97)
						{
						double temp = value;
						for(; temp > 1000 && !flag; k++)
						{
							temp /= 10;							
						}
						flag = true;
						Number n = new Number(1, j + 1, value/Math.pow(10, k));
						sheet.addCell(n);
						n = new Number(2, j + 1, intensity);
						sheet.addCell(n);
						j++;
						}
						
					}
					double var = 0;
					for (double [] values : dataSet)
					{
						double value = values[i];
						var += Math.pow(avg - value, 2) / (double)dataSet.size();
					}
					
					Label label = new Label(0, 0, "ID");
					sheet.addCell(label);
					label = new Label(1, 0, "wartosc cechy");
					sheet.addCell(label);
					label = new Label(2, 0, "natezenie");
					sheet.addCell(label);
					label = new Label(3, 0, "Nr cechy");
					sheet.addCell(label);
					label = new Label(4, 0, "srednia");
					sheet.addCell(label);
					label = new Label(5, 0, "wariancja");
					sheet.addCell(label);
					label = new Label(6, 0, "przeskalowanie");
					sheet.addCell(label);
					Number n = new Number(4, 1, avg);
					sheet.addCell(n);
					n = new Number(3, 1, i);
					sheet.addCell(n);
					n = new Number(5, 1, var);
					sheet.addCell(n);	
					n = new Number(6, 1, k);
					sheet.addCell(n);	
					
					close();
			}			
			int [] index = {6,7,14,16};
			
			for(int m=0; m<index.length; m++)
				for(int n=m+1; n<index.length; n++)
				{
					workbook = Workbook.createWorkbook(new File(index[m]+"x"+index[n]+".xls"));
					sheet = workbook.createSheet("First Sheet", 0);
					
					int j = 0;
					int k1 = 0;
					int k2 = 0;
					boolean flag1 = false;
					boolean flag2 = false;
					for (double [] values : dataSet)
					{
						double value1 = values[index[m]];
						double value2 = values[index[n]];
						if(Math.random() > 0.97)
						{
						double temp = value1;
						for(; temp > 1000  && !flag1; k1++)
						{
							temp /= 10;							
						}
						temp = value2;
						for(; temp > 10000  && !flag2; k2++)
						{
							temp /= 10;							
						}
						flag1 = flag2 = true;
						Number nr = new Number(1, j + 1, value1/Math.pow(10, k1));
						sheet.addCell(nr);
						nr = new Number(2, j + 1, value2/Math.pow(10, k2));
						sheet.addCell(nr);
						j++;
						}
						
					}
					
					Label label = new Label(1, 0, "cecha "+index[m]);
					sheet.addCell(label);
					label = new Label(2, 0, "cecha "+index[n]);
					sheet.addCell(label);
					label = new Label(3, 0, "przeskalowanie cechy "+index[m]);
					sheet.addCell(label);
					label = new Label(4, 0, "przeskalowanie cechy "+index[n]);
					sheet.addCell(label);
					Number nr = new Number(3, 1, k1);
					sheet.addCell(nr);
					nr = new Number(4, 1, k2);
					sheet.addCell(nr);
					
					close();
				}
			
		}
		workbook = Workbook.createWorkbook(new File("1dzienroboczy.xls"));
		sheet = workbook.createSheet("First Sheet", 0);
		
		int k = (int)(Math.random() * 10000.) + 10000;
		boolean flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			
			if(tab[2]==1 && tab[4]==0)
				flag = true;
		}
		int j=0;
		flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			double value = tab[5];
			
			Number n = new Number(1, j + 1, value);
			sheet.addCell(n);
			j++;
			if(tab[2]==2 && tab[4]==0)
				flag = true;
		}
		close();
		workbook = Workbook.createWorkbook(new File("5dniRoboczych.xls"));
		sheet = workbook.createSheet("First Sheet", 0);
		
		k = (int)(Math.random() * 10000.) + 10000;
		flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			
			if(tab[2]==1 && tab[4]==0)
				flag = true;
		}
		j=0;
		flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			double value = tab[5];
			
			Number n = new Number(1, j + 1, value);
			sheet.addCell(n);
			j++;
			if(tab[2]==6 && tab[4]==0)
				flag = true;
		}
		close();
		workbook = Workbook.createWorkbook(new File("weekend.xls"));
		sheet = workbook.createSheet("First Sheet", 0);
		
		k = (int)(Math.random() * 10000.) + 10000;
		flag = false;
		System.out.println(k);
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			
			if(tab[2]==6 && tab[4]==0)
				flag = true;
		}
		j=0;
		flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			double value = tab[5];
			
			Number n = new Number(1, j + 1, value);
			sheet.addCell(n);
			j++;
			if(tab[2]==1 && tab[4]==0)
				flag = true;
		}
		close();
		workbook = Workbook.createWorkbook(new File("tydzien.xls"));
		sheet = workbook.createSheet("First Sheet", 0);
		
		k = (int)(Math.random() * 10000.) + 10000;
		flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			
			if(tab[2]==1 && tab[4]==0)
				flag = true;
		}
		j=0;
		flag = false;
		for(; k<dataSet.size() && !flag; k++)
		{
			double [] tab = dataSet.get(k);
			double value = tab[5];
			
			Number n = new Number(1, j + 1, value);
			sheet.addCell(n);
			
			j++;
			
			if(tab[2]==1 && tab[4]==0)
				flag = true;
		}
		close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RowsExceededException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	private LinkedList<double []> toListOfArrays(LinkedList<Measurement> dataSet)
	{
		LinkedList<double []> result = new LinkedList<double []>();
	
		for(Measurement measurement: dataSet)
			result.add(measurement.getValues());
	
		return result;
	}
	public void generate(String fileName)
	{
		try {
			workbook = Workbook.createWorkbook(new File(fileName+".xls"));
			sheet = workbook.createSheet("First Sheet", 0);

			Label label = new Label(0, 0, "ID");
			sheet.addCell(label);
			label = new Label(1, 0, "Data");
			sheet.addCell(label);
			label = new Label(2, 0, "Natężenie ruchu");
			sheet.addCell(label);
			label = new Label(3, 0, "Średnia prędkość pojazdów");
			sheet.addCell(label);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RowsExceededException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void addMeasurement(Measurement measurement) {
		index++;

		try {
			Number id = new Number(0,index, measurement.getId());
			sheet.addCell(id);

			Number dateTime = new Number(1, index,
					measurement.getTime()/10000);
			sheet.addCell(dateTime);

			Number intensity = new Number(2, index,
					measurement.getIntensity());
			sheet.addCell(intensity);

			Number avgSpeed = new Number(3, index,
					measurement.getAvgSpeed());
			sheet.addCell(avgSpeed);

		} catch (Exception e) {
			System.err.println(e);
		}
	}

	public void close() {
		try {
			workbook.write();
			workbook.close();
		} catch (Exception e) {
			System.err.println(e);
		}
	}
}
